public Class AccountEmailTriggerHandler{

static Set<Id> accemailupdateid=new Set<Id>();
static Set<Id> accemailinsertid=new Set<Id>();

public void AccountEmailInsert(List<Account_Email__c> accemaillist){
     Set<Id> emailid=new Set<Id>();
     Set<Id> accid=new Set<Id>();
    List<Account_Email__c> oldaccountemaillist=new List<Account_Email__c>();
    List<Account_Email__c> oldaccountemailupdatelist=new List<Account_Email__c>();
     Account_Email__c email=new Account_Email__c();
    
    if(accemaillist!=null&&accemaillist.size()>0){   
     email= accemaillist[0];
        for(Account_Email__c accemail: accemaillist){
            emailid.add(accemail.Id);
            accid.add(accemail.Account__c);
        }       
        oldaccountemaillist=[select Account__c,Preferred__c from Account_Email__c where Preferred__c=true AND Account__c IN:accid AND Id NOT IN:emailid];
        
    for(Account_Email__c accemail: accemaillist){
                      
            system.debug('&&oldaccountemaillist'+ oldaccountemaillist);
            system.debug('&&accemaillist'+ accemaillist);
            if(oldaccountemaillist!=null && oldaccountemaillist.size()>0){                 
                      
                   if(accemail.Preferred__c==true) {      
                    for(Account_Email__c oldemail : oldaccountemaillist){
                             oldemail.Preferred__c=false;
                             oldaccountemailupdatelist.add(oldemail);
                             accemailinsertid.add(oldemail.Id);       
                    }
                  }
                    
            }else{
                email.Preferred__c=true;
            }                             
        }
        
        system.debug('&&oldaccountemailupdatelist'+ oldaccountemailupdatelist);
      if(!oldaccountemailupdatelist.IsEmpty()){
          update oldaccountemailupdatelist;
      }
    
    }
    
 }
public void AccountEmailUpdate(List<Account_Email__c> newaccemaillist,List<Account_Email__c> oldaccemaillist){
     Set<Id> emailid=new Set<Id>();
     Set<Id> accid=new Set<Id>();
    List<Account_Email__c> oldaccountemaillist=new List<Account_Email__c>();
    List<Account_Email__c> oldaccountemailupdatelist=new List<Account_Email__c>();
    
    if(newaccemaillist!=null&&newaccemaillist.size()>0){    
        for(Account_Email__c accemail: newaccemaillist){
            emailid.add(accemail.Id);
            accid.add(accemail.Account__c);
        }       
        oldaccountemaillist=[select Account__c,Preferred__c from Account_Email__c where Preferred__c=true AND Account__c IN:accid AND Id NOT IN:emailid];
        
        
            for(Account_Email__c newaccemail: newaccemaillist){
                for(Account_Email__c oldaccemail: oldaccemaillist){
                    if((newaccemail.Preferred__c==true && oldaccemail.Preferred__c==false && newaccemail.Account__c==oldaccemail.Account__c)){ 
                        for(Account_Email__c accvalue: oldaccountemaillist){
                              accvalue.Preferred__c=false;        
                              oldaccountemailupdatelist.add(accvalue);
                              accemailupdateid.add(accvalue.Id);                            
                          } 
                    } else{
                    for(Account_Email__c accval: newaccemaillist){
                          
                            if(accemailupdateid.contains(accval.id) ){
                            }else{
                            if(accemailinsertid.IsEmpty()&&(newaccemail.Preferred__c==false&& oldaccemail.Preferred__c==true))
                             trigger.new[0].addError('cannot update');  
                            }
                        }
                    
                    }
                
                }
            }
           
        }
        
        if(!oldaccountemailupdatelist.isEmpty()){
                try{
                    
                    update oldaccountemailupdatelist;
                }catch(Exception e){
                    system.debug('# Exception while updating : '+e);
                }
            }                                  
    }
    public void ContactEmailDelete(List<Account_Email__c> accountemaillist){
        if(accountemaillist!=null&&accountemaillist.size()>0){
            system.debug('@@accountemaillist '+accountemaillist);
            for(Account_Email__c accemail: accountemaillist){
            
            if(accemail.Preferred__c==true){
                    trigger.old[0].addError('Cannot delete prefered record');  
                }
            }
        
        }

    }
    
/************************************************************************
        Purpose     : Test Class                  
        Parameters  : None
        Returns     : None
***********************************************************************/
    @isTest(SeeAllData=false)
     static public void testAccountEmailTriggerHandler() {
         
         PIMS_Reserved_Id__c pimsid=new PIMS_Reserved_Id__c();
         pimsid.PIMS_Id__c='0000-0000';
         pimsid.Used__c=false;
         insert pimsid;
         
         Account acc=new Account();
         acc.Name='test';
         acc.Type='SSO';
         insert acc;
         
         Account_Email__c accemail=new Account_Email__c();
         accemail.Account__c=acc.id;
         accemail.Email_Type__c='Email at Home';
         accemail.Email__c='test@a.com';
         accemail.Preferred__c=true;
         insert accemail;
         update accemail;
         
         Account_Email__c accemail0=new Account_Email__c();
         accemail0.Account__c=acc.id;
         accemail0.Email_Type__c='Email at Home';
         accemail0.Email__c='test@a.com';
         accemail0.Preferred__c=true;
         insert accemail0;
         
         Account_Email__c accemail1=new Account_Email__c();
         accemail1.Account__c=acc.id;
         accemail1.Email_Type__c='Email at Home';
         accemail1.Email__c='test@a.com';
         accemail1.Preferred__c=false;
         insert accemail1;
         accemail1.Preferred__c=true;
         update accemail1;
         
         Account_Email__c accemail2=new Account_Email__c();
         accemail2.Account__c=acc.id;
         accemail2.Email_Type__c='Email at Home';
         accemail2.Email__c='test@a.com';
         accemail2.Preferred__c=false;
         insert accemail2;
         delete accemail2;
     }   
}